package com.shengqin.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shengqin.common.pojo.CommonPage;
import com.shengqin.common.pojo.CommonResult;
import com.shengqin.config.model.TestProjectConfig;
import com.shengqin.entity.*;
import com.shengqin.pojo.plan.summary.SummaryExportModel;
import com.shengqin.pojo.summary.SummaryQueryParam;
import com.shengqin.service.*;
import com.shengqin.utils.CustomCellWriteWidthConfig;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static com.shengqin.utils.ProcessTimeResultUtil.processRunResult;

@RestController
@RequestMapping("admin/v1/summary")
@Slf4j
public class SummaryResultController {

    @Resource
    private ISummaryResultService summaryResultService;
    @Resource
    private ITestResultService testResultService;
    @Resource
    private IPlanService planService;
    @Resource
    private IPlanStudentService planStudentService;
    @Resource
    private SysHealthProjectService projectService;
    @Resource
    private IPlanApplyProjectService planApplyProjectService;
    @Resource
    private ISchoolService schoolService;
    @Resource
    private TestProjectConfig projectConfig;

    private final List<String> excelFixHeaders = new ArrayList<>();
    private final List<String> heightWeightHeads = new ArrayList<>();

    private final List<String> lowSchoolProjectHeaders = new ArrayList<>();
    private final List<String> highSchoolProjectHeaders = new ArrayList<>();

    @PostConstruct
    public void init() {
        excelFixHeaders.add("学校名称");
        excelFixHeaders.add("年级编号");
        excelFixHeaders.add("班级名称");
        excelFixHeaders.add("学籍号");
        excelFixHeaders.add("姓名");
        excelFixHeaders.add("性别");

        heightWeightHeads.add("身高");
        heightWeightHeads.add("体重");
        heightWeightHeads.add("BMI");

        lowSchoolProjectHeaders.add("肺活量");
        lowSchoolProjectHeaders.add("50米跑");
        lowSchoolProjectHeaders.add("坐位体前屈");
        lowSchoolProjectHeaders.add("一分钟跳绳");
        lowSchoolProjectHeaders.add("一分钟仰卧起坐");
        lowSchoolProjectHeaders.add("50米×8往返跑");

        highSchoolProjectHeaders.add("肺活量");
        highSchoolProjectHeaders.add("50米跑");
        highSchoolProjectHeaders.add("坐位体前屈");
        highSchoolProjectHeaders.add("一分钟仰卧起坐");
        highSchoolProjectHeaders.add("立定跳远");
        highSchoolProjectHeaders.add("引体向上");
        highSchoolProjectHeaders.add("1000米");
        highSchoolProjectHeaders.add("800米");

    }

    @Operation(summary = "查询计划列表 根据学校ID分组")
    @PostMapping("queryPlanList")
    public CommonResult<List<Plan>> queryPlanList(@RequestBody SummaryQueryParam queryParam) {
        return CommonResult.data(summaryResultService.queryPlanList(queryParam));
    }

    @Operation(summary = "查询计划列表 根据学校ID 查询分组")
    @PostMapping("queryData")
    public CommonResult<Map<String, Object>> queryData(@RequestBody SummaryQueryParam queryParam) {
        return CommonResult.data(summaryResultService.queryData(queryParam));
    }


    private void exportHealthSummary(SummaryResult queryParam, HttpServletResponse response) throws IOException {
        Plan plan = planService.getById(queryParam.getPlanId());
        List<SummaryResult> summaryResultList = summaryResultService.getExportList(queryParam);
        List<String> studyCodes = summaryResultList.stream().map(SummaryResult::getStudyCode).collect(Collectors.toList());
        List<PlanStudent> planStudentList = planStudentService.queryByPlanIdAndStudyCodes(plan.getId(), studyCodes);
        Map<String, PlanStudent> planStudentMap = planStudentList.stream().collect(Collectors.toMap(PlanStudent::getStudyCode, s -> s));
        List<SummaryExportModel> hsms = new ArrayList<>();
        summaryResultList.forEach(summaryResult -> {
            SummaryExportModel hsm = new SummaryExportModel();
            PlanStudent planStudent = planStudentMap.getOrDefault(summaryResult.getStudyCode(), null);
            if (planStudent != null) {
                BeanUtils.copyProperties(planStudent, hsm);
            }
            BeanUtils.copyProperties(summaryResult, hsm);

            hsms.add(hsm);
        });

        ClassPathResource classPathresource = new ClassPathResource("excel/小学评分等级汇总.xlsx");
        if (queryParam.getDownloadGradeId() == 21) {
            classPathresource = new ClassPathResource("excel/高校评分等级汇总.xlsx");
        }

        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("评分等级汇总", String.valueOf(StandardCharsets.UTF_8)).replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        try (InputStream inputStream = classPathresource.getInputStream();
             ServletOutputStream outputStream = response.getOutputStream();
             ExcelWriter excelWriter = EasyExcel.write(outputStream, SummaryExportModel.class)
                     .excelType(ExcelTypeEnum.XLS)
                     .withTemplate(inputStream).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            excelWriter.fill(new FillWrapper("hs", hsms), writeSheet);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Operation(summary = "导出汇总成绩")
    @GetMapping("exportSummary")
    public void exportSummaryList(SummaryResult queryParam, HttpServletResponse response) throws IOException {
        Plan plan = planService.getById(queryParam.getPlanId());
        List<SummaryResult> hasSummaryResultList = summaryResultService.getExportList(queryParam);
        if (plan.getExamFlag()) {
            generateExamSummary(hasSummaryResultList, plan, queryParam, response);
        } else {
            generateHealthSummary(hasSummaryResultList, plan, queryParam, response);
        }

    }

    private void generateHealthSummary(List<SummaryResult> hasSummaryResultList, Plan plan, SummaryResult queryParam, HttpServletResponse response) throws IOException {
        Set<String> projectNames = new HashSet<>();
        QueryWrapper<PlanStudent> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(PlanStudent::getPlanId, plan.getId());
        if (queryParam.getDownloadGradeId() != null) {
            if (queryParam.getDownloadGradeId() <= 16) {
                wrapper.lambda().le(PlanStudent::getGradeId, queryParam.getDownloadGradeId());
            } else {
                wrapper.lambda().ge(PlanStudent::getGradeId, queryParam.getDownloadGradeId());
            }
        }
        List<PlanStudent> planStudentList = planStudentService.list(wrapper);
        projectConfig.getProjectModelList().forEach(p -> projectNames.add(p.getLabel()));
        List<SummaryResult> summaryResultList = new ArrayList<>();
        Set<Integer> schoolIds = planStudentList.stream().map(PlanStudent::getSchoolId).collect(Collectors.toSet());
        List<School> schoolList = schoolService.listByIds(schoolIds);
        Map<Integer, School> schoolMap = schoolList.stream().collect(Collectors.toMap(School::getId, s -> s));
        Map<String, List<SummaryResult>> studySummaryMap = hasSummaryResultList.stream().collect(Collectors.groupingBy(SummaryResult::getStudyCode));
        if (!CollectionUtils.isEmpty(hasSummaryResultList)) {
            summaryResultList.addAll(hasSummaryResultList);
            planStudentList.forEach(planStudent -> {
                if (!studySummaryMap.containsKey(planStudent.getStudyCode())) {
                    SummaryResult newSummaryResult = new SummaryResult();
                    BeanUtils.copyProperties(planStudent, newSummaryResult);
                    newSummaryResult.setPlanName(plan.getName());
                    newSummaryResult.setSchoolName(schoolMap.get(planStudent.getSchoolId()).getName());
                    summaryResultList.add(newSummaryResult);
                }
            });
        }

        boolean isHighSchool = queryParam.getDownloadGradeId() == 21;

        List<List<String>> headers = buildExcelHeads(new ArrayList<>(isHighSchool ? highSchoolProjectHeaders : lowSchoolProjectHeaders), true);

        if (queryParam.getExportType() == 1) {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("评分等级汇总", String.valueOf(StandardCharsets.UTF_8)).replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            List<List<Object>> dataList = generateSummaryResultList(summaryResultList, queryParam, isHighSchool, plan);


            EasyExcel.write(response.getOutputStream())
                    // 这里放入动态头
                    .head(headers)
                    .registerWriteHandler(new CustomCellWriteWidthConfig()).sheet("sheet1").doWrite(dataList);
        } else {
            response.reset();
            response.setContentType("application/octet-stream;charset=UTF-8");
            String filename = System.currentTimeMillis() + ".zip";
            response.addHeader("Content-Disposition", "inline; filename=" + URLUtil.encode(filename, CharsetUtil.CHARSET_UTF_8));

            Map<String, List<SummaryResult>> schoolSummaryMap = summaryResultList.stream().collect(Collectors.groupingBy(SummaryResult::getSchoolName));
            List<File> files = new ArrayList<>();

            schoolSummaryMap.forEach((schoolName, summaryResults) -> {
                List<List<Object>> dataList = generateSummaryResultList(summaryResults, queryParam, isHighSchool, plan);
                File file = new File(schoolName + ".xlsx");
                EasyExcel.write(file)
                        // 这里放入动态头
                        .head(headers)
                        .registerWriteHandler(new CustomCellWriteWidthConfig()).sheet("sheet1").doWrite(dataList);
                files.add(file);
            });

            File targetZipFile = new File(plan.getName() + "成绩评分等级汇总.zip");
            generateZip(targetZipFile, files, false);
            OutputStream out = response.getOutputStream();
            FileChannel fileChannel = new RandomAccessFile(targetZipFile, "r").getChannel();
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            WritableByteChannel writableByteChannel = Channels.newChannel(out);
            while (fileChannel.read(byteBuffer) != -1) {
                byteBuffer.flip();
                while (byteBuffer.hasRemaining()) {
                    writableByteChannel.write(byteBuffer);
                }
                byteBuffer.clear();
            }
            fileChannel.close();
            writableByteChannel.close();
            out.close();
            if (targetZipFile.exists()) {
                targetZipFile.delete();
            }
            if (!CollectionUtils.isEmpty(files)) {
                files.forEach(File::delete);
            }
        }
    }

    private boolean isExportAll(SummaryResult queryParam) {
        if (queryParam.getSchoolId() != null) {
            return false;
        }
        if (StringUtils.hasLength(queryParam.getName())) {
            return false;
        }
        if (StringUtils.hasLength(queryParam.getStudyCode())) {
            return false;
        }
        if (StringUtils.hasLength(queryParam.getSex())) {
            return false;
        }
        if (queryParam.getGradeId() != null) {
            return false;
        }
        if (StringUtils.hasLength(queryParam.getTestQueryDate())) {
            return false;
        }
        return true;
    }

    private void generateExamSummary(List<SummaryResult> hasSummaryResultList, Plan plan, SummaryResult queryParam, HttpServletResponse response) throws IOException {
        boolean exportType = isExportAll(queryParam);
        List<PlanApplyProject> applyProjectList;
        if (exportType) {
            QueryWrapper<PlanApplyProject> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(PlanApplyProject::getPlanId, plan.getId());
            if (queryParam.getDownloadGradeId() != null) {
                if (queryParam.getDownloadGradeId() <= 16) {
                    wrapper.lambda().le(PlanApplyProject::getGradeId, queryParam.getDownloadGradeId());
                } else {
                    wrapper.lambda().ge(PlanApplyProject::getGradeId, queryParam.getDownloadGradeId());
                }
            }
            applyProjectList = planApplyProjectService.list(wrapper);
        } else {
            Set<String> studyCodes = hasSummaryResultList.stream().map(SummaryResult::getStudyCode).collect(Collectors.toSet());
            applyProjectList = planApplyProjectService.queryByPlanIdAndStudyCodes(plan.getId(), studyCodes);
        }
        List<SysHealthProject> healthProjects = projectService.listByTemplateId(plan.getTemplateId());
        Set<String> projectNames = healthProjects.stream().sorted((a, b) -> a.getProjectName().compareToIgnoreCase(b.getProjectName())).map(SysHealthProject::getProjectName).collect(Collectors.toSet());
        Map<String, List<PlanApplyProject>> studyApplyProjectMap;
        if (CollectionUtils.isEmpty(applyProjectList) || CollectionUtils.isEmpty(hasSummaryResultList)) {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("评分等级汇总", String.valueOf(StandardCharsets.UTF_8)).replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            List<List<Object>> dataList = new ArrayList<>();

            EasyExcel.write(response.getOutputStream())
                    // 这里放入动态头
                    .head(buildExcelHeads(new ArrayList<>(projectNames), false))
                    .registerWriteHandler(new CustomCellWriteWidthConfig()).sheet("sheet1").doWrite(dataList);
        } else {
            studyApplyProjectMap = applyProjectList.stream().collect(Collectors.groupingBy(PlanApplyProject::getStudyCode));
            Set<Integer> schoolIds = applyProjectList.stream().map(PlanApplyProject::getSchoolId).collect(Collectors.toSet());
            List<School> schoolList = schoolService.listByIds(schoolIds);
            Map<Integer, School> schoolMap = schoolList.stream().collect(Collectors.toMap(School::getId, s -> s));
            List<SummaryResult> summaryResultList = new ArrayList<>();
            Map<String, List<SummaryResult>> studySummaryMap = hasSummaryResultList.stream().collect(Collectors.groupingBy(SummaryResult::getStudyCode));
            if (!CollectionUtils.isEmpty(hasSummaryResultList)) {
                summaryResultList.addAll(hasSummaryResultList);
                applyProjectList.forEach(planApplyProject -> {
                    if (!studySummaryMap.containsKey(planApplyProject.getStudyCode())) {
                        SummaryResult newSummaryResult = new SummaryResult();
                        BeanUtils.copyProperties(planApplyProject, newSummaryResult);
                        newSummaryResult.setPlanName(plan.getName());
                        newSummaryResult.setSchoolName(schoolMap.get(planApplyProject.getSchoolId()).getName());
                        summaryResultList.add(newSummaryResult);
                    }
                });
            }

            if (queryParam.getExportType() == 1) {
                response.setContentType("application/vnd.ms-excel");
                response.setCharacterEncoding("utf-8");
                String fileName = URLEncoder.encode("评分等级汇总", String.valueOf(StandardCharsets.UTF_8)).replaceAll("\\+", "%20");
                response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
                List<List<Object>> dataList = generateSummaryResultList(summaryResultList, queryParam, projectNames, plan, studyApplyProjectMap);

                EasyExcel.write(response.getOutputStream())
                        // 这里放入动态头
                        .head(buildExcelHeads(new ArrayList<>(projectNames), false))
                        .registerWriteHandler(new CustomCellWriteWidthConfig()).sheet("sheet1").doWrite(dataList);
            } else {
                response.reset();
                response.setContentType("application/octet-stream;charset=UTF-8");
                String filename = System.currentTimeMillis() + ".zip";
                response.addHeader("Content-Disposition", "inline; filename=" + URLUtil.encode(filename, CharsetUtil.CHARSET_UTF_8));

                Map<String, List<SummaryResult>> schoolSummaryMap = summaryResultList.stream().collect(Collectors.groupingBy(SummaryResult::getSchoolName));
                List<File> files = new ArrayList<>();

                schoolSummaryMap.forEach((schoolName, summaryResults) -> {
                    List<List<Object>> dataList = generateSummaryResultList(summaryResults, queryParam, projectNames, plan, studyApplyProjectMap);
                    File file = new File(schoolName + ".xlsx");
                    EasyExcel.write(file)
                            // 这里放入动态头
                            .head(buildExcelHeads(new ArrayList<>(projectNames), false))
                            .registerWriteHandler(new CustomCellWriteWidthConfig()).sheet("sheet1").doWrite(dataList);
                    files.add(file);
                });

                File targetZipFile = new File(plan.getName() + "成绩评分等级汇总.zip");
                generateZip(targetZipFile, files, false);
                OutputStream out = response.getOutputStream();
                FileChannel fileChannel = new RandomAccessFile(targetZipFile, "r").getChannel();
                ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                WritableByteChannel writableByteChannel = Channels.newChannel(out);
                while (fileChannel.read(byteBuffer) != -1) {
                    byteBuffer.flip();
                    while (byteBuffer.hasRemaining()) {
                        writableByteChannel.write(byteBuffer);
                    }
                    byteBuffer.clear();
                }
                fileChannel.close();
                writableByteChannel.close();
                out.close();
                if (targetZipFile.exists()) {
                    targetZipFile.delete();
                }
                if (!CollectionUtils.isEmpty(files)) {
                    files.forEach(File::delete);
                }
            }
        }
    }

    public static void generateZip(File targetZipFile, List<File> sourceFiles, boolean dirWithFlag) {
        if (CollUtil.isNotEmpty(sourceFiles)) {
            File[] fileArr = sourceFiles.toArray(new File[]{});
            ZipUtil.zip(targetZipFile, dirWithFlag, fileArr);
        }
    }

    public File byte2Pdf(byte[] pdfOut, String name) {
        File file = new File(name);
        try (FileOutputStream fos = new FileOutputStream(file)) {
            fos.write(pdfOut);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    private List<List<Object>> generateSummaryResultList(List<SummaryResult> summaryResultList, SummaryResult queryParam, Boolean isHighSchool, Plan plan) {

        List<SysHealthProject> healthProjects = projectService.listByTemplateId(plan.getTemplateId());
        Map<String, SysHealthProject> projectMap = healthProjects.stream().collect(Collectors.toMap(t -> t.getProjectName() + "_" + t.getGradeId(), p -> p));

        List<List<Object>> dataList = new ArrayList<>();
        summaryResultList.forEach(summaryResult -> {
            AtomicReference<BigDecimal> totalScore = new AtomicReference<>(BigDecimal.ZERO);
            List<Object> data = new ArrayList<>();
            data.add(summaryResult.getSchoolName());
            data.add(summaryResult.getGradeId());
            data.add(summaryResult.getClassesName());
            data.add(summaryResult.getStudyCode());
            data.add(summaryResult.getName());
            data.add(summaryResult.getSex());

            List<TestResult> testResults = summaryResult.getTestResultList();
            Map<String, List<TestResult>> testResultMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(testResults)) {
                testResultMap = testResults.stream().collect(Collectors.groupingBy(TestResult::getPrjName));
            }

            for (String projectName : heightWeightHeads) {
                String prjName = projectName;
                if (projectName.equalsIgnoreCase("身高体重")) {
                    prjName = "BMI";
                }
                List<TestResult> testRList = testResultMap.get(prjName);
                if (!CollectionUtils.isEmpty(testRList)) {
                    TestResult testResult = testRList.get(0);
                    if (testResult.getFinalScore() != null) {
                        totalScore.set(totalScore.get().add(testResult.getFinalScore()));
                    }
                    data.add(testResult.getResult());
                    if (!prjName.equals("身高") && !prjName.equals("体重")) {
                        if (queryParam.getScoreType().equals(1)) {
                            data.add(testResult.getFinalScore());
                        } else {
                            data.add(testResult.getScore());
                        }
                        data.add(testResult.getLevel());
                    }

                } else {
                    data.add("");
                    if (!prjName.equals("身高") && !prjName.equals("体重")) {
                        data.add("");
                        data.add("");
                    }
                }
            }

            List<String> otherProjectHeads = isHighSchool ? highSchoolProjectHeaders : lowSchoolProjectHeaders;

            Map<String, List<TestResult>> finalTestResultMap = testResultMap;
            otherProjectHeads.forEach(projectName -> {
                if (!plan.getExamFlag()) {
                    List<TestResult> testRList = finalTestResultMap.get(projectName);
                    if (!CollectionUtils.isEmpty(testRList)) {
                        TestResult testResult = testRList.get(0);
                        if (testResult.getFinalScore() != null) {
                            totalScore.set(totalScore.get().add(testResult.getFinalScore()));
                        }
                        SysHealthProject healthProject = projectMap.getOrDefault(projectName + "_" + testResult.getGradeId(), null);
                        if(healthProject != null){
                            data.add(processRunResult(testResult.getResult(),healthProject.getPrjUnit(),queryParam.getExportTimeType(),healthProject.getProjectName()));
                        } else {
                            data.add(testResult.getResult());
                        }
                        if (queryParam.getScoreType().equals(1)) {
                            data.add(testResult.getFinalScore());
                        } else {
                            BigDecimal score = testResult.getScore();
                            data.add(score);
                        }
                        data.add(testResult.getLevel());
                    } else {
                        data.add("");
                        data.add("");
                        data.add("");
                    }
                } else {
                    data.add("");
                    data.add("");
                    data.add("");
                }
            });

            data.add(totalScore.get());
            data.add(summaryResult.getTotalLevel() != null ? summaryResult.getTotalLevel() : "");

            dataList.add(data);
        });

        return dataList;
    }

    private List<List<Object>> generateSummaryResultList(List<SummaryResult> summaryResultList, SummaryResult queryParam, Set<String> projectNames, Plan plan, Map<String, List<PlanApplyProject>> applyProjectMap) {

        List<SysHealthProject> healthProjects = projectService.listByTemplateId(plan.getTemplateId());
        Map<String, SysHealthProject> projectMap = healthProjects.stream().collect(Collectors.toMap(t -> t.getProjectName() + "_" + t.getGradeId(), p -> p));

        List<List<Object>> dataList = new ArrayList<>();
        summaryResultList.forEach(summaryResult -> {
            AtomicReference<BigDecimal> totalScore = new AtomicReference<>(BigDecimal.ZERO);
            List<Object> data = new ArrayList<>();
            data.add(summaryResult.getSchoolName());
            data.add(summaryResult.getGradeId());
            data.add(summaryResult.getClassesName());
            data.add(summaryResult.getStudyCode());
            data.add(summaryResult.getName());
            data.add(summaryResult.getSex());

            List<TestResult> testResults = summaryResult.getTestResultList();
            Map<String, List<TestResult>> testResultMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(testResults)) {
                testResultMap = testResults.stream().collect(Collectors.groupingBy(TestResult::getPrjName));
            }
            PlanApplyProject studyApplyProject;
            List<PlanApplyProject> studyApplyProjects = applyProjectMap.getOrDefault(summaryResult.getStudyCode(), null);
            if (!CollectionUtils.isEmpty(studyApplyProjects)) {
                studyApplyProject = studyApplyProjects.get(0);
            } else {
                studyApplyProject = null;
            }

            List<String> heightAndWeightHeadList = projectNames.stream().filter(s -> s.equals("身高") || s.equals("体重") || s.equalsIgnoreCase("BMI")).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(heightAndWeightHeadList)) {
                for (String projectName : heightWeightHeads) {
                    if (heightAndWeightHeadList.contains(projectName)) {
                        List<TestResult> testRList = testResultMap.get(projectName);
                        if (!CollectionUtils.isEmpty(testRList)) {
                            TestResult testResult = testRList.get(0);
                            if (testResult.getFinalScore() != null) {
                                totalScore.set(totalScore.get().add(testResult.getFinalScore()));
                            }
                            data.add(testResult.getResult());
                            if (!projectName.equals("身高") && !projectName.equals("体重")) {
                                if (queryParam.getScoreType().equals(1)) {
                                    data.add(testResult.getFinalScore());
                                } else {
                                    data.add(testResult.getScore());
                                }
                            }

                        } else {
                            data.add("");
                            if (!projectName.equals("身高") && !projectName.equals("体重")) {
                                data.add("");
                            }
                        }
                    }
                }
            }

            List<String> otherProjectHeads = projectNames.stream().filter(s -> !s.equals("身高") && !s.equals("体重") && !s.equalsIgnoreCase("BMI")).collect(Collectors.toList());

            Map<String, List<TestResult>> finalTestResultMap = testResultMap;
            otherProjectHeads.forEach(projectName -> {
                boolean hasProject = studyApplyProject != null && studyApplyProject.getProjectNames().contains(projectName);
                if (!plan.getExamFlag() || hasProject) {
                    List<TestResult> testRList = finalTestResultMap.get(projectName);
                    if (!CollectionUtils.isEmpty(testRList)) {
                        TestResult testResult = testRList.get(0);
                        if (testResult.getFinalScore() != null) {
                            totalScore.set(totalScore.get().add(testResult.getFinalScore()));
                        }
                        SysHealthProject healthProject = projectMap.getOrDefault(projectName + "_" + testResult.getGradeId(), null);
                        if(healthProject != null){
                            data.add(processRunResult(testResult.getResult(),healthProject.getPrjUnit(),queryParam.getExportTimeType(),healthProject.getProjectName()));
                        } else {
                            data.add(testResult.getResult());
                        }
                        if (queryParam.getScoreType().equals(1)) {
                            data.add(testResult.getFinalScore());
                        } else {
                            BigDecimal score = testResult.getScore();
                            data.add(score);
                        }
                    } else {
                        data.add("");
                        data.add("");
                    }
                } else {
                    data.add("");
                    data.add("");
                }
            });

            data.add(totalScore.get());
            data.add(summaryResult.getTotalLevel() != null ? summaryResult.getTotalLevel() : "");

            dataList.add(data);
        });

        return dataList;
    }

    private List<List<String>> buildExcelHeads(List<String> projectNames, Boolean health) {

        List<List<String>> headers = new ArrayList<>();
        for (String excelFixHeader : excelFixHeaders) {
            List<String> head = new ArrayList<>();
            head.add(excelFixHeader);
            headers.add(head);
        }

        if (!health) {
            List<String> heightAndWeightHeadList = projectNames.stream().filter(s -> s.equals("身高") || s.equals("体重") || s.equalsIgnoreCase("BMI")).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(heightAndWeightHeadList)) {
                for (String projectName : heightWeightHeads) {
                    if (heightAndWeightHeadList.contains(projectName)) {
                        List<String> head = new ArrayList<>();
                        head.add(projectName);
                        headers.add(head);
                        if (!projectName.equals("身高") && !projectName.equals("体重")) {
                            List<String> scoreHead = new ArrayList<>();
                            scoreHead.add("得分");
                            headers.add(scoreHead);
                        }
                    }
                }
            }
        } else {
            for (String projectName : heightWeightHeads) {
                List<String> head = new ArrayList<>();
                head.add(projectName);
                headers.add(head);
                if (!projectName.equals("身高") && !projectName.equals("体重")) {
                    List<String> scoreHead = new ArrayList<>();
                    scoreHead.add("得分");
                    headers.add(scoreHead);
                    List<String> levelHead = new ArrayList<>();
                    levelHead.add("等级");
                    headers.add(levelHead);
                }
            }
        }


        List<String> otherProjectHeads = projectNames.stream().filter(s -> !s.equals("身高") && !s.equals("体重") && !s.equals("BMI")).collect(Collectors.toList());

        for (String projectName : otherProjectHeads) {
            List<String> head = new ArrayList<>();
            head.add(projectName);
            headers.add(head);
            List<String> scoreHead = new ArrayList<>();
            scoreHead.add("得分");
            headers.add(scoreHead);
            if (health) {
                List<String> levelHead = new ArrayList<>();
                levelHead.add("等级");
                headers.add(levelHead);
            }
        }

        List<String> head = new ArrayList<>();
        head.add("总分");
        headers.add(head);

        if (health) {
            List<String> levelHead = new ArrayList<>();
            levelHead.add("等级");
            headers.add(levelHead);
        }

        return headers;
    }

    @PostMapping("page")
    public CommonResult<Page<SummaryResult>> getPage(@RequestBody CommonPage<SummaryResult> queryPage) {
        Page<SummaryResult> resultPage = summaryResultService.getPage(queryPage);
        return CommonResult.data(resultPage);
    }

    @PostMapping("delete")
    public CommonResult<Boolean> delete(@RequestBody SummaryResult summaryResult) {
        return CommonResult.data(summaryResultService.removeById(summaryResult.getId()));
    }
}
